import asyncio
import json
from pathlib import Path
from typing import List, Dict, Optional
from datetime import datetime
from app.config import settings
from app.utils.logger import logger
from app.services.video_splitter import VideoSplitter
from app.services.qwen_service import QwenVLService
from app.services.internvl_service import InternVLService

class LargeVideoAnalyzerFixed:
    """修复版大视频分析服务"""
    
    def __init__(self):
        self.video_splitter = VideoSplitter()
        self.qwen_service = QwenVLService()
        self.internvl_service = InternVLService()
        self.max_concurrent_analysis = 3  # 最大并发分析数
        
        # 保持配置文件中的超时时间设置，用于视频分析
        # self.qwen_service.timeout 使用配置文件中的 QWEN_TIMEOUT (300秒)
        
    async def analyze_large_video(
        self,
        video_path: Path,
        prompt: str,
        split_method: str = "duration",  # duration, scene, auto
        segment_duration: int = 60,
        max_segments: int = 20,
        analysis_mode: str = "sequential",  # sequential, parallel, hybrid
        min_segment_duration: int = 10  # 最小片段时长
    ) -> Dict:
        """分析大视频文件（修复版）"""
        try:
            logger.info(f"开始分析大视频: {video_path}")
            
            # 快速检查AI服务可用性
            logger.info("检查AI服务可用性...")
            qwen_available = False
            try:
                qwen_available = await asyncio.wait_for(
                    self.qwen_service.test_connection(), 
                    timeout=10.0
                )
            except asyncio.TimeoutError:
                logger.warning("Qwen服务连接超时")
            except Exception as e:
                logger.warning(f"Qwen服务检查失败: {e}")
            
            logger.info(f"AI服务状态 - Qwen: {'可用' if qwen_available else '不可用'}")
            
            # 检查视频文件是否存在
            if not video_path.exists():
                raise FileNotFoundError(f"视频文件不存在: {video_path}")
            
            logger.info(f"视频文件存在，大小: {video_path.stat().st_size} bytes")
            
            # 1. 检查是否需要拆分
            video_info = await self.video_splitter._get_video_info(video_path)
            logger.info(f"视频信息: {video_info}")
            
            # 如果AI服务不可用，返回离线分析结果
            if not qwen_available:
                return await self._create_offline_analysis_result(video_path, prompt, video_info)
            
            # 如果视频较小，直接分析
            if (video_info['duration'] <= segment_duration and 
                video_info['file_size'] <= settings.QWEN_MAX_VIDEO_SIZE_MB * 1024 * 1024):
                return await self._analyze_single_video_safe(video_path, prompt, video_info)
            
            # 2. 拆分视频
            split_result = await self._split_video(
                video_path, split_method, segment_duration, max_segments, min_segment_duration
            )
            
            logger.info(f"拆分结果: need_split={split_result.get('need_split')}, segments_count={len(split_result.get('segments', []))}")
            
            if not split_result['need_split']:
                logger.info("视频无需拆分，直接分析")
                return await self._analyze_single_video_safe(video_path, prompt, video_info)
            
            # 3. 分析各个片段
            analysis_results = await self._analyze_segments_safe(
                split_result['segments'], prompt, analysis_mode
            )
            
            # 4. 汇总结果
            final_result = await self._merge_analysis_results(
                analysis_results, split_result, prompt
            )
            
            # 5. 保存完整分析结果
            await self._save_analysis_result(split_result['video_id'], final_result)
            
            logger.info(f"大视频分析完成: {video_path}")
            return final_result
            
        except Exception as e:
            logger.error(f"大视频分析失败: {e}")
            # 返回错误信息而不是抛出异常
            return {
                "success": False,
                "error": str(e),
                "type": "error",
                "message": f"分析失败: {str(e)}"
            }
    
    async def _create_offline_analysis_result(self, video_path: Path, prompt: str, video_info: Dict) -> Dict:
        """创建离线分析结果"""
        logger.info("创建离线分析结果")
        
        return {
            "type": "offline_analysis",
            "video_path": str(video_path),
            "segment_count": 1,
            "successful_segments": 0,
            "total_duration": video_info.get('duration', 0),
            "split_method": "offline",
            "overall_summary": f"离线模式分析结果\\n\\n"
                             f"视频文件: {video_path.name}\\n"
                             f"时长: {video_info.get('duration', 0):.1f}秒\\n"
                             f"分辨率: {video_info.get('width', 0)}x{video_info.get('height', 0)}\\n"
                             f"帧率: {video_info.get('fps', 0):.1f}fps\\n"
                             f"文件大小: {video_info.get('file_size', 0) / (1024*1024):.1f}MB\\n\\n"
                             f"注意: 当前AI服务不可用，这是基础的文件信息。\\n"
                             f"请检查网络连接后重新分析以获得详细的AI分析结果。\\n\\n"
                             f"原始提示词: {prompt}",
            "segment_results": [{
                "segment_index": 0,
                "status": "offline",
                "analysis_result": f"离线模式 - 无法进行AI分析\\n"
                                 f"视频: {video_path.name}\\n"
                                 f"建议: 修复AI服务连接后重试"
            }],
            "key_insights": {
                "key_actions": ["检查网络连接"],
                "important_moments": ["AI服务连接失败"],
                "technical_details": ["Qwen服务不可用"],
                "main_topics": ["离线模式", "网络问题"],
                "improvement_suggestions": ["检查网络配置", "确认AI服务状态", "重新尝试分析"]
            },
            "analyzed_at": datetime.now().isoformat(),
            "offline_mode": True
        }
    
    async def _analyze_single_video_safe(self, video_path: Path, prompt: str, video_info: Dict) -> Dict:
        """安全的单视频分析"""
        try:
            # 生成视频URL
            filename = video_path.name
            video_url = f"{settings.VIDEO_BASE_URL}/videos/{filename}"
            
            # 尝试使用Qwen3-VL分析
            try:
                result = await asyncio.wait_for(
                    self.qwen_service.analyze_video_by_url(video_url, prompt),
                    timeout=60.0  # 1分钟超时
                )
            except asyncio.TimeoutError:
                logger.warning("Qwen分析超时，使用备用方案")
                result = self._create_fallback_result(video_path, prompt, video_info)
            except Exception as qwen_error:
                logger.warning(f"Qwen分析失败，使用备用方案: {qwen_error}")
                result = self._create_fallback_result(video_path, prompt, video_info)
            
            return {
                "type": "single_video",
                "video_path": str(video_path),
                "video_url": video_url,
                "analysis_result": result,
                "prompt": prompt,
                "analyzed_at": datetime.now().isoformat()
            }
            
        except Exception as e:
            logger.error(f"单视频分析失败: {e}")
            return self._create_fallback_result(video_path, prompt, video_info)
    
    def _create_fallback_result(self, video_path: Path, prompt: str, video_info: Dict) -> str:
        """创建备用分析结果"""
        return f"视频文件: {video_path.name}\\n" \
               f"时长: {video_info.get('duration', 0):.1f}秒\\n" \
               f"分辨率: {video_info.get('width', 0)}x{video_info.get('height', 0)}\\n" \
               f"帧率: {video_info.get('fps', 0):.1f}fps\\n" \
               f"文件大小: {video_info.get('file_size', 0) / (1024*1024):.1f}MB\\n\\n" \
               f"注意: AI服务暂时不可用，无法进行详细分析。\\n" \
               f"原始提示词: {prompt}"
    
    async def _analyze_segments_safe(self, segments: List[Dict], prompt: str, mode: str) -> List[Dict]:
        """安全的片段分析"""
        if mode == "parallel":
            return await self._analyze_segments_parallel_safe(segments, prompt)
        else:
            return await self._analyze_segments_sequential_safe(segments, prompt)
    
    async def _analyze_segments_sequential_safe(self, segments: List[Dict], prompt: str) -> List[Dict]:
        """安全的顺序分析片段"""
        results = []
        
        for i, segment in enumerate(segments):
            try:
                segment_prompt = self._create_segment_prompt(prompt, segment, i, len(segments))
                
                # 尝试分析，带超时
                try:
                    analysis_result = await asyncio.wait_for(
                        self.qwen_service.analyze_video_by_url(segment['url'], segment_prompt),
                        timeout=60.0
                    )
                    status = "success"
                except asyncio.TimeoutError:
                    logger.warning(f"片段 {i+1} 分析超时")
                    analysis_result = f"片段 {i+1} 分析超时\\n{segment['filename']}\\n时间段: {segment.get('start_time', 0):.1f}s - {segment.get('end_time', 0):.1f}s"
                    status = "timeout"
                except Exception as e:
                    logger.warning(f"片段 {i+1} 分析失败: {e}")
                    analysis_result = f"片段 {i+1} 分析失败\\n{segment['filename']}\\n错误: {str(e)}"
                    status = "failed"
                
                results.append({
                    "segment_index": i,
                    "segment_info": segment,
                    "prompt": segment_prompt,
                    "analysis_result": analysis_result,
                    "analyzed_at": datetime.now().isoformat(),
                    "status": status
                })
                
            except Exception as e:
                logger.error(f"片段处理异常 {i+1}: {e}")
                results.append({
                    "segment_index": i,
                    "segment_info": segment,
                    "analysis_result": f"处理异常: {str(e)}",
                    "analyzed_at": datetime.now().isoformat(),
                    "status": "error"
                })
        
        return results
    
    # 其他方法保持不变，从原文件复制...
    async def _split_video(self, video_path: Path, method: str, duration: int, max_segments: int, min_duration: int = 10) -> Dict:
        """拆分视频"""
        if method == "scene":
            return await self.video_splitter.split_video_by_scenes(
                video_path, min_segment_duration=min_duration, max_segments=max_segments
            )
        elif method == "duration":
            return await self.video_splitter.split_video_by_duration(
                video_path, duration, max_segments, min_duration
            )
        elif method == "auto":
            # 自动选择：先尝试场景检测，失败则用时长拆分
            try:
                return await self.video_splitter.split_video_by_scenes(
                    video_path, min_segment_duration=min_duration, max_segments=max_segments
                )
            except Exception as e:
                logger.warning(f"场景拆分失败，使用时长拆分: {e}")
                return await self.video_splitter.split_video_by_duration(
                    video_path, duration, max_segments, min_duration
                )
        else:
            raise ValueError(f"不支持的拆分方法: {method}")
    
    def _create_segment_prompt(self, base_prompt: str, segment: Dict, index: int, total: int) -> str:
        """创建片段分析提示词"""
        return f"""{base_prompt}

【片段信息】
片段位置: 第{index + 1}段，共{total}段
时间段: {segment.get('start_time', 0):.1f}s - {segment.get('end_time', 0):.1f}s
片段时长: {segment.get('duration', 0):.1f}秒

【分析要求】
1. 重点关注这个时间段内的具体内容
2. 描述时请标注大概的时间点
3. 如果是系列片段的一部分，请注意与前后内容的连贯性
4. 提供这个片段的关键信息摘要"""

    async def _merge_analysis_results(self, analysis_results: List[Dict], split_result: Dict, prompt: str) -> Dict:
        """汇总分析结果"""
        # 简化版汇总
        successful_segments = sum(1 for r in analysis_results if r.get('status') == 'success')
        
        # 生成整体摘要
        overall_summary = f"视频分析完成\\n\\n"
        overall_summary += f"总片段数: {len(analysis_results)}\\n"
        overall_summary += f"成功分析: {successful_segments}\\n"
        overall_summary += f"分析方法: {split_result.get('split_method', 'unknown')}\\n\\n"
        
        if successful_segments > 0:
            overall_summary += "各片段分析结果:\\n"
            for i, result in enumerate(analysis_results[:3]):  # 只显示前3个
                if result.get('status') == 'success':
                    content = result.get('analysis_result', '')[:100]
                    overall_summary += f"片段{i+1}: {content}...\\n"
        else:
            overall_summary += "注意: 所有片段分析都失败了，可能是AI服务连接问题。"
        
        return {
            "type": "large_video_analysis",
            "segment_count": len(analysis_results),
            "successful_segments": successful_segments,
            "total_duration": split_result.get('total_duration', 0),
            "split_method": split_result.get('split_method', 'unknown'),
            "overall_summary": overall_summary,
            "segment_results": analysis_results,
            "key_insights": {
                "key_actions": ["视频分析完成"],
                "important_moments": [f"成功分析{successful_segments}个片段"],
                "technical_details": [f"使用{split_result.get('split_method', 'unknown')}拆分方法"],
                "main_topics": ["大视频分析"],
                "improvement_suggestions": ["检查失败片段的原因"] if successful_segments < len(analysis_results) else []
            },
            "analyzed_at": datetime.now().isoformat()
        }
    
    async def _save_analysis_result(self, video_id: str, result: Dict):
        """保存分析结果"""
        try:
            # 简化版保存
            logger.info(f"保存分析结果: {video_id}")
        except Exception as e:
            logger.warning(f"保存分析结果失败: {e}")